//package org.codehaus.activemq.transport.gnet;
//
//import EDU.oswego.cs.dl.util.concurrent.Latch;
//import EDU.oswego.cs.dl.util.concurrent.SynchronizedBoolean;
//import java.io.ByteArrayOutputStream;
//import java.io.DataInputStream;
//import java.io.DataOutputStream;
//import java.io.IOException;
//import java.io.InputStream;
//import java.io.PrintStream;
//import java.net.InetAddress;
//import java.net.InetSocketAddress;
//import java.net.URI;
//import java.net.UnknownHostException;
//import java.nio.ByteBuffer;
//import java.util.ArrayList;
//import javax.jms.JMSException;
//import org.apache.commons.logging.Log;
//import org.apache.commons.logging.LogFactory;
//import org.apache.geronimo.network.SelectorManager;
//import org.apache.geronimo.network.protocol.AbstractProtocol;
//import org.apache.geronimo.network.protocol.DownPacket;
//import org.apache.geronimo.network.protocol.PlainDownPacket;
//import org.apache.geronimo.network.protocol.Protocol;
//import org.apache.geronimo.network.protocol.ProtocolException;
//import org.apache.geronimo.network.protocol.SocketProtocol;
//import org.apache.geronimo.network.protocol.UpPacket;
//import org.apache.geronimo.pool.ClockPool;
//import org.apache.geronimo.pool.ThreadPool;
//import org.codehaus.activemq.message.Packet;
//import org.codehaus.activemq.message.WireFormat;
//import org.codehaus.activemq.transport.AbstractTransportChannel;
//
//public class GTransportChannel extends AbstractTransportChannel
//{
//  private static final Log log = LogFactory.getLog(GTransportChannel.class);
//  private SynchronizedBoolean closed;
//  private SynchronizedBoolean started;
//  private Protocol protocol;
//  private Latch dispatchLatch;
//  private ThreadPool threadPool;
//  private WireFormat wireFormat;
//
//  protected GTransportChannel(WireFormat wireFormat, ThreadPool tp)
//  {
//    this.wireFormat = wireFormat;
//    this.closed = new SynchronizedBoolean(false);
//    this.started = new SynchronizedBoolean(false);
//    this.dispatchLatch = new Latch();
//    this.threadPool = tp;
//  }
//
//  public GTransportChannel(WireFormat wireFormat, Protocol protocol, ThreadPool tp)
//  {
//    this(wireFormat, tp);
//    init(protocol);
//  }
//
//  public GTransportChannel(WireFormat wireFormat, URI remoteLocation, URI localLocation, SelectorManager sm, ThreadPool tp, ClockPool cp)
//    throws UnknownHostException, ProtocolException
//  {
//    this(wireFormat, tp);
//
//    SocketProtocol sp = new SocketProtocol();
//    sp.setTimeout(30000L);
//    if (localLocation != null) {
//      sp.setInterface(new InetSocketAddress(InetAddress.getByName(localLocation.getHost()), localLocation.getPort()));
//    }
//
//    sp.setAddress(new InetSocketAddress(InetAddress.getByName(remoteLocation.getHost()), remoteLocation.getPort()));
//
//    sp.setSelectorManager(sm);
//
//    init(sp);
//    sp.setup();
//  }
//
//  private void init(Protocol protocol)
//  {
//    this.protocol = protocol;
//
//    protocol.setUpProtocol(new AbstractProtocol() {
//      public void setup() {
//      }
//
//      public void drain() {
//      }
//
//      public void teardown() {
//      }
//
//      public void sendUp(UpPacket p) {
//        try {
//          GTransportChannel.log.trace("AQUIRING: " + GTransportChannel.this.dispatchLatch);
//          GTransportChannel.this.dispatchLatch.acquire();
//          GTransportChannel.log.trace("AQUIRED: " + GTransportChannel.this.dispatchLatch);
//
//          GTransportChannel.this.dispatch(p);
//        }
//        catch (InterruptedException e) {
//          GTransportChannel.log.warn("Caught exception dispatching packet: " + p + ". Reason: " + e, e);
//        }
//      }
//
//      public void sendDown(DownPacket p)
//        throws ProtocolException
//      {
//        getDownProtocol().sendDown(p);
//      }
//
//      public void flush() throws ProtocolException {
//        getDownProtocol().flush();
//      }
//    });
//  }
//
//  private void dispatch(UpPacket p) {
//    try {
//      Packet packet = toPacket(p);
//      log.trace("<<<< SENDING UP <<<< " + packet);
//      if (packet != null)
//        doConsumePacket(packet);
//    }
//    catch (IOException e)
//    {
//      log.warn("Caught exception dispatching packet: " + p + ". Reason: " + e, e);
//    }
//  }
//
//  public void stop()
//  {
//    super.stop();
//    if (this.closed.commit(false, true))
//      try {
//        this.protocol.drain();
//      }
//      catch (Exception e) {
//        log.trace(toString() + " now closed");
//      }
//  }
//
//  public void start()
//    throws JMSException
//  {
//    if (this.started.commit(false, true))
//    {
//      this.dispatchLatch.release();
//    }
//  }
//
//  public void asyncSend(Packet packet)
//    throws JMSException
//  {
//    try
//    {
//      if (log.isTraceEnabled()) {
//        log.trace(">>>> ASYNC SENDING DOWN >>>> " + packet);
//      }
//
//      synchronized (this.protocol) {
//        this.protocol.sendDown(toPlainDownPacket(packet));
//      }
//    }
//    catch (IOException e) {
//      System.out.println("Caught: " + e);
//      e.printStackTrace();
//      JMSException jmsEx = new JMSException("asyncSend failed " + e.getMessage());
//
//      jmsEx.setLinkedException(e);
//      throw jmsEx;
//    }
//    catch (ProtocolException e) {
//      System.out.println("Caught: " + e);
//      e.printStackTrace();
//      JMSException jmsEx = new JMSException("asyncSend failed " + e.getMessage());
//
//      jmsEx.setLinkedException(e);
//      throw jmsEx;
//    }
//  }
//
//  public boolean isMulticast() {
//    return false;
//  }
//
//  protected PlainDownPacket toPlainDownPacket(Packet mqpacket)
//    throws IOException, JMSException
//  {
//    ByteArrayOutputStream baos = new ByteArrayOutputStream();
//    DataOutputStream dos = new DataOutputStream(baos);
//    this.wireFormat.writePacket(mqpacket, dos);
//    dos.close();
//    ArrayList list = new ArrayList(1);
//    ByteBuffer buffer = ByteBuffer.wrap(baos.toByteArray());
//    buffer.limit(buffer.capacity());
//    list.add(buffer);
//    PlainDownPacket packet = new PlainDownPacket();
//    packet.setBuffers(list);
//    return packet;
//  }
//
//  protected Packet toPacket(UpPacket packet) throws IOException {
//    ByteBuffer buffer = packet.getBuffer();
//    InputStream is = new InputStream(buffer) { private final ByteBuffer val$buffer;
//
//      public int read() { if (!this.val$buffer.hasRemaining()) {
//          return -1;
//        }
//        int rc = 0xFF & this.val$buffer.get();
//        return rc; }
//
//      public synchronized int read(byte[] bytes, int off, int len)
//      {
//        len = Math.min(len, this.val$buffer.remaining());
//        this.val$buffer.get(bytes, off, len);
//        return len;
//      }
//    };
//    DataInputStream dis = new DataInputStream(is);
//    return this.wireFormat.readPacket(dis);
//  }
//
//  public String toString()
//  {
//    return "GTransportChannel: " + this.protocol;
//  }
//}